home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / usenet / volume11 / bt / part02 < prev    next >
Encoding:
Internet Message Format  |  1990-12-11  |  12.2 KB

  1. Path: uunet!ogicse!zephyr.ens.tek.com!tekred!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v11i076:  bt - Broken Throne, multiplayer realtime conquest game, Part02/02
  5. Message-ID: <6596@tekred.CNA.TEK.COM>
  6. Date: 21 Nov 90 20:16:59 GMT
  7. Sender: news@tekred.CNA.TEK.COM
  8. Lines: 520
  9. Approved: billr@saab.CNA.TEK.COM
  10. Posted: Wed Nov 21 12:16:59 1990
  11.  
  12. Submitted-by: Tom Boutell <boutell@freezer.it.udel.edu>
  13. Posting-number: Volume 11, Issue 76
  14. Archive-name: bt/Part02
  15. Environment: INET sockets, curses
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 2 (of 2)."
  24. # Contents:  Makefile interface.c types.h
  25. # Wrapped by billr@saab on Wed Nov 21 12:13:26 1990
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'Makefile'\"
  29. else
  30. echo shar: Extracting \"'Makefile'\" \(306 characters\)
  31. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  32. Xbtclient: client.o pack.o
  33. X    cc client.o pack.o -o btclient -ltermcap -lcurses -ltermlib
  34. X
  35. Xbtserver: bt.o pack.o interface.o
  36. X    cc bt.o pack.o interface.o -o btserver
  37. X
  38. Xclient.o: client.c
  39. X    cc -c -g client.c
  40. Xpack.o: pack.c
  41. X    cc -c -g pack.c
  42. Xinterface.o: interface.c
  43. X    cc -c -g interface.c
  44. Xbt.o: bt.c
  45. X    cc -c -g bt.c
  46. END_OF_FILE
  47. if test 306 -ne `wc -c <'Makefile'`; then
  48.     echo shar: \"'Makefile'\" unpacked with wrong size!
  49. fi
  50. # end of 'Makefile'
  51. fi
  52. if test -f 'interface.c' -a "${1}" != "-c" ; then 
  53.   echo shar: Will not clobber existing file \"'interface.c'\"
  54. else
  55. echo shar: Extracting \"'interface.c'\" \(8905 characters\)
  56. sed "s/^X//" >'interface.c' <<'END_OF_FILE'
  57. X
  58. X/* interface.c: Socket communications support& medium- level message
  59. X * passing functions. Copyright (C) 1990 Tom Boutell on original portions.
  60. X * All low- level socket code drawn with appreciation from:
  61. X * SOCK.C
  62. X * Copyright (C)1989 Dr Evil Laboratories
  63. X * This code written by Ray Moody, Roy Riggs, Mitch Adler,
  64. X * Bill Burdick, and Steven Grady
  65. X * No one makes any guarantees about anything.  This file maybe 
  66. X * freely distributed and modified as long as this header remains intact.  
  67. X */
  68. X#include <stdio.h>
  69. X#include <sys/types.h>
  70. X#include <sys/time.h>
  71. X#include <sys/socket.h>
  72. X#include <netinet/in.h>
  73. X#include <string.h>
  74. X#include <ctype.h>
  75. X#include <signal.h>
  76. X#include <netdb.h>
  77. X#include <varargs.h>
  78. X
  79. X#include "types.h"
  80. X#include "pack.h"
  81. X#include "bt.h"
  82. X#include "interface.h"
  83. X
  84. X#define DEBUG
  85. X#undef DEBUG
  86. X#ifdef DEBUG
  87. X#define debug printf
  88. X#else
  89. X#define debug 0+
  90. X#define perror 0+
  91. X#endif
  92. X
  93. X#define SECONDSLIMIT 0L
  94. X#define MICROSECONDSLIMIT 1L
  95. X
  96. X#define LINE_LEN 1024
  97. X#define LOST_CARRIER_MSG "F"
  98. X
  99. X#define NONE (fd_set *) NULL
  100. X#define NEVER (struct timeval *) NULL
  101. X#define IGNORE (struct sockaddr *) NULL
  102. X
  103. Xfd_set active;
  104. Xstruct sockaddr_in sc_in;
  105. Xint s;
  106. Xchar cur_input[LINE_LEN];
  107. Xchar *curhostname = "";
  108. Xint playerids[20];
  109. Xchar outputline[256];
  110. Xvoid setupinterface() {
  111. X  int current;
  112. X  init_socket(2727);
  113. X  playertext=(outputline+1);
  114. X  for (current=1; (current<=totalplayers); current++) {
  115. X    playerids[current]=new_player(0);
  116. X    players[current].live=1;
  117. X    printf("Player %d has joined.\n",current);
  118. X    outputline[0]=_YOUARE;
  119. X    outputline[1]=64+current;
  120. X    outputline[2]=0;
  121. X    w_p(playerids[current],outputline,strlen(&outputline[0])+1);
  122. X    }
  123. X} 
  124. X
  125. Xvoid tellplayer(player)
  126. X  int player;
  127. X{
  128. X  outputline[0]=_TEXT;
  129. X  w_p(playerids[player],outputline,strlen(&outputline[0])+1);
  130. X} 
  131. X
  132. Xvoid broadcast(messagetype,details)
  133. X  char messagetype;
  134. X  void* details;
  135. X{
  136. X  location where;
  137. X  int thisplayer;
  138. X  int current;
  139. X  outputline[0]=messagetype;
  140. X  switch (messagetype) {
  141. X   
  142. X    case _HEXSTATUS:
  143. X      where=*(location*)details;
  144. X      outputline[1]=64+where.x;
  145. X      outputline[2]=64+where.y;
  146. X      outputline[3]=64+map[where.x][where.y].terrain;
  147. X      packint(4,map[where.x][where.y].population);
  148. X      packint(7,map[where.x][where.y].lastuse);
  149. X      packint(10,map[where.x][where.y].troops);
  150. X      outputline[13]=map[where.x][where.y].owner+64;
  151. X      outputline[14]=NULL;
  152. X      break;
  153. X    case _PLAYERSTATUS:
  154. X      thisplayer=*(int*)details;
  155. X      outputline[1]=thisplayer+64;
  156. X      packint(2,players[thisplayer].action);
  157. X      packint(5,players[thisplayer].hexes);
  158. X      packint(8,players[thisplayer].troops);
  159. X      packint(11,players[thisplayer].population);
  160. X      packint(14,players[thisplayer].citadels);
  161. X      outputline[17]=players[thisplayer].start.x+64;
  162. X      outputline[18]=players[thisplayer].start.y+64;
  163. X      outputline[19]=NULL;
  164. X      break;
  165. X    case _PLAYERDEAD:
  166. X      thisplayer=*(int*)details;
  167. X      outputline[1]=thisplayer+64;
  168. X      outputline[2]=NULL;
  169. X      break;
  170. X    case _ACTION:
  171. X      outputline[1]=NULL;    
  172. X      break;
  173. X    case _STARTUP:
  174. X      outputline[1]=totalplayers+64;
  175. X      outputline[2]=NULL;
  176. X      break;
  177. X    case _TEXT:
  178. X      strcpy(&outputline[1],(char*) details);
  179. X      break;
  180. X    case _END:
  181. X      outputline[1]=NULL;
  182. X  }
  183. X  for (current=0; (current<=totalplayers); current++) {
  184. X    if (outputline[0]==_END) {
  185. X    }
  186. X    if (players[current].live) {
  187. X      w_p(playerids[current],outputline,strlen(outputline)+1); 
  188. X    }   
  189. X  }
  190. X}    
  191. X
  192. Xint getrequest(thisplayer,requesttype,specific)
  193. X  int* thisplayer;
  194. X  char* requesttype;
  195. X  char* specific;
  196. X{
  197. X  char* received;
  198. X  static int sweep;
  199. X  int oldsweep;
  200. X  sweep++;
  201. X  if ((sweep>totalplayers) || (sweep<=0))
  202. X    sweep=1;
  203. X  oldsweep=sweep;
  204. X  while (players[sweep].live==0) {
  205. X    sweep++;
  206. X    if (sweep>totalplayers)
  207. X      sweep=1;
  208. X    if (sweep==oldsweep)
  209. X      return 0;
  210. X  }
  211. X  received=read_player(playerids[sweep]);
  212. X  *thisplayer=sweep;
  213. X  if (*received==NULL)
  214. X    return 0;
  215. X  *requesttype=received[0];
  216. X  strcpy(specific,(received+=1));
  217. X  return 1;
  218. X  }           
  219. X
  220. X
  221. Xvoid shutdowninterface() {
  222. X  disconnect_all();
  223. X}
  224. X  
  225. X
  226. X/* - PD Socket code begins here.
  227. X * init_socket() - intialize our socket, port is the port number to use
  228. X *                 call this once at the beginning of your code
  229. X */
  230. X
  231. Xint init_socket(port)
  232. X    int port;
  233. X{
  234. X    setbuf(stdout, (char *)0);
  235. X    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  236. X        perror("socket");
  237. X        return 0;
  238. X    }
  239. X    sc_in.sin_family = AF_INET;
  240. X    sc_in.sin_addr.s_addr = INADDR_ANY;
  241. X    sc_in.sin_port = htons((u_short) port);
  242. X    if (bind(s, (struct sockaddr *) &sc_in, sizeof(sc_in)) < 0) {
  243. X        perror("bind");
  244. X        return 0;
  245. X    }
  246. X    if (listen(s, 5) < 0) {
  247. X        perror("listen");
  248. X        return 0;
  249. X    }
  250. X
  251. X    FD_ZERO(&active);
  252. X
  253. X    return 1;
  254. X}
  255. X
  256. X
  257. X/*
  258. X * disconnect_all() - throws everyone off
  259. X */
  260. X
  261. Xint disconnect_all()
  262. X{
  263. X    register int i;
  264. X    
  265. X    for (i = 0; i < FD_SETSIZE; i++) {
  266. X        if (FD_ISSET(i, &active))
  267. X            (void) disconnect(i);
  268. X    }
  269. X    return 1;
  270. X}
  271. X
  272. X
  273. X/*
  274. X * shut-down -- kills all connections and exits the pgm
  275. X */
  276. X
  277. Xint shut_down()
  278. X{
  279. X    (void) disconnect_all();
  280. X    exit(0);
  281. X}
  282. X
  283. X
  284. X/* hostfrom() - returns a string containing an ascii name for the host
  285. X *              that the passed socket s is connected to.  Note that the
  286. X *              string is in static space.  If you want to munge with it,
  287. X *              make a copy.
  288. X */
  289. X
  290. Xchar *hostfrom(i)
  291. X    int i;
  292. X{
  293. X    struct sockaddr_in from;
  294. X    int fromlen = sizeof(from);
  295. X    struct hostent *host;
  296. X    struct in_addr addr;
  297. X
  298. X    if (getpeername(i, &from, &fromlen) < 0) {
  299. X        perror("getpeername");
  300. X        return NULL;
  301. X    }
  302. X    
  303. X    addr = from.sin_addr;
  304. X    if ((host = gethostbyaddr(&addr, sizeof(addr), AF_INET)) == NULL) {
  305. X        debug("gethostbyaddr failed");
  306. X        return NULL;
  307. X    }
  308. X        
  309. X    return curhostname = host->h_name;
  310. X}
  311. X
  312. X
  313. X/*
  314. X * hostname() - returns curhostname
  315. X */
  316. X
  317. Xchar *hostname()
  318. X{
  319. X    return curhostname;
  320. X}
  321. X
  322. X
  323. X/*
  324. X * new_player() - call this routine in your main loop to allow new
  325. X *                players to join.  returns a playerId or -1 if no one
  326. X *                wants to join.
  327. X *                if wait == 0, then put your process to sleep until
  328. X *                someone new tries to connect.
  329. X */
  330. X
  331. Xint new_player(wait)
  332. X    int wait;   /* 0 - wait for activity, else don't wait */
  333. X{
  334. X    fd_set readfds;
  335. X    int j;
  336. X    struct timeval *pWaitTime, waitTime;
  337. X
  338. X    pWaitTime = &waitTime;
  339. X    
  340. X    if (0 == wait) {
  341. X        pWaitTime = NEVER;
  342. X    } else {
  343. X        pWaitTime->tv_sec = SECONDSLIMIT;
  344. X        pWaitTime->tv_usec = MICROSECONDSLIMIT;
  345. X    }
  346. X
  347. X    bcopy((char *) &active, (char *) &readfds, sizeof(active));
  348. X
  349. X    FD_SET(s, &readfds);
  350. X
  351. X    if (select(FD_SETSIZE, &readfds, NONE, NONE, pWaitTime) < 0) {
  352. X        perror("select");
  353. X        return -1;
  354. X    }
  355. X    if (FD_ISSET(s, &readfds)) {
  356. X        if ((j = accept(s, IGNORE, (int *) 0)) < 0) {
  357. X            return -1;
  358. X        }
  359. X        FD_SET(j, &active);
  360. X        curhostname = hostfrom(j);
  361. X        debug("Test Host=%s\n", curhostname);
  362. X        return j;
  363. X    } else {
  364. X        return -1;
  365. X    }
  366. X}
  367. X
  368. X
  369. X/*
  370. X * disconnect() - drop the player with the given id
  371. X */
  372. X
  373. Xint disconnect(id)
  374. X    int id;
  375. X{
  376. X    if (FD_ISSET(id, &active)) {
  377. X        debug("** Just dropped %d\n", id);
  378. X        FD_CLR(id, &active);
  379. X        if (close(id) < 0) {
  380. X            perror("close");
  381. X            return 0;
  382. X        }
  383. X    } else {
  384. X        debug("** Just tried to drop someone not connected\n");
  385. X        return 0;
  386. X    }
  387. X    return 1;
  388. X}
  389. X
  390. X
  391. X/*
  392. X * read_player() - This routine returns the next string from the player
  393. X *                 connected to descriptor playerFd. If there is no
  394. X *                 input it returns the empty string. If the connection
  395. X *                 is lost the string LOST_CARRIER_MSG is returned.
  396. X *                 NOTE: control characters are replaced by spaces
  397. X *                       and it is null terminated at the first nl/cr
  398. X */
  399. X
  400. Xchar *read_player(playerFd)
  401. X    int playerFd;
  402. X{
  403. X    fd_set readfds;
  404. X    struct timeval waitTime;
  405. X    
  406. X    waitTime.tv_sec = SECONDSLIMIT;
  407. X    waitTime.tv_usec = MICROSECONDSLIMIT;
  408. X
  409. X    bcopy((char *) &active, (char *) &readfds, sizeof(active));
  410. X
  411. X    if (select(FD_SETSIZE, &readfds, NONE, NONE, &waitTime) < 0) {
  412. X        perror("select");
  413. X        return("");
  414. X    }
  415. X
  416. X    if (FD_ISSET(playerFd, &readfds)) {
  417. X        int nbytes, i;
  418. X        
  419. X        nbytes = read(playerFd, cur_input, LINE_LEN);
  420. X        if (nbytes < 0) {
  421. X            perror("read");
  422. X            disconnect(playerFd);
  423. X            return(LOST_CARRIER_MSG);
  424. X        } else if (nbytes == 0) {
  425. X            disconnect(playerFd);
  426. X            return(LOST_CARRIER_MSG);
  427. X        } else {
  428. X/* Don't need control editing    for(i=0; i<nbytes; ++i) {
  429. X                if (iscntrl(cur_input[i])) {
  430. X                    if (cur_input[i]=='\n' ||
  431. X                        cur_input[i]=='\r')
  432. X                        cur_input[i] = '\n';
  433. X                    else
  434. X                        cur_input[i] = ' ';
  435. X                }
  436. X            }
  437. X*/
  438. X            if (nbytes != LINE_LEN) {
  439. X                cur_input[nbytes] = '\0';
  440. X            } else {
  441. X                cur_input[LINE_LEN - 1] = '\0';
  442. X            }
  443. X
  444. X            return((char *) cur_input);
  445. X        }
  446. X    }
  447. X    return("");
  448. X}
  449. X
  450. X
  451. X/*
  452. X * write_player() - write to id, a string with the given length
  453. X */
  454. X
  455. Xint w_p(id, str, len)
  456. X    int id, len;
  457. X    char *str;
  458. X{
  459. X    if (id > -1) {
  460. X        if (!FD_ISSET(id, &active)) {
  461. X            debug("** Tried to write to closed id #%d.\n", id);
  462. X            return 0;
  463. X        } else if (write(id, str, len) < 0) {
  464. X            perror("Write");
  465. X            return 0;
  466. X        }
  467. X    }
  468. X    return 1;
  469. X}
  470. X
  471. X
  472. X
  473. X
  474. END_OF_FILE
  475. if test 8905 -ne `wc -c <'interface.c'`; then
  476.     echo shar: \"'interface.c'\" unpacked with wrong size!
  477. fi
  478. # end of 'interface.c'
  479. fi
  480. if test -f 'types.h' -a "${1}" != "-c" ; then 
  481.   echo shar: Will not clobber existing file \"'types.h'\"
  482. else
  483. echo shar: Extracting \"'types.h'\" \(282 characters\)
  484. sed "s/^X//" >'types.h' <<'END_OF_FILE'
  485. Xtypedef struct {
  486. X  char terrain;
  487. X  int population;
  488. X  int lastuse;
  489. X  int troops;
  490. X  int owner;
  491. X} hex;
  492. X
  493. Xtypedef struct {
  494. X  int x;
  495. X  int y;
  496. X} location;
  497. X
  498. Xtypedef struct {
  499. X  int action;
  500. X  int hexes;
  501. X  int troops;
  502. X  int population;
  503. X  int citadels;
  504. X  int live;
  505. X  location start;
  506. X} player;
  507. X
  508. END_OF_FILE
  509. if test 282 -ne `wc -c <'types.h'`; then
  510.     echo shar: \"'types.h'\" unpacked with wrong size!
  511. fi
  512. # end of 'types.h'
  513. fi
  514. echo shar: End of archive 2 \(of 2\).
  515. cp /dev/null ark2isdone
  516. MISSING=""
  517. for I in 1 2 ; do
  518.     if test ! -f ark${I}isdone ; then
  519.     MISSING="${MISSING} ${I}"
  520.     fi
  521. done
  522. if test "${MISSING}" = "" ; then
  523.     echo You have unpacked both archives.
  524.     rm -f ark[1-9]isdone
  525. else
  526.     echo You still need to unpack the following archives:
  527.     echo "        " ${MISSING}
  528. fi
  529. ##  End of shell archive.
  530. exit 0
  531.